package com.zmn.oms.dubbo.impl.zmn.third.zhimi;

import org.apache.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.google.common.collect.Lists;
import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dto2.ResponseDTO;
import com.zmn.common.utils.collection.CollectionUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.reflect.BeanMapper;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.oms.common.dto.ResultDTO;
import com.zmn.oms.common.exception.OmsBaseException;
import com.zmn.oms.common.vo.KVDict;
import com.zmn.oms.dubbo.dto.zmn.third.zhimi.*;
import com.zmn.oms.dubbo.interfaces.zmn.third.zhimi.ZhimiRemoteService;
import com.zmn.oms.dubbo.utils.DubboConsts;
import com.zmn.oms.third.zhimi.ZhimiConsts;
import com.zmn.oms.third.zhimi.dto.CheckResultDTO;
import com.zmn.oms.third.zhimi.dto.SaveBuyDateResulstDTO;
import com.zmn.oms.third.zhimi.entity.ZhimiOrderExtend;
import com.zmn.oms.third.zhimi.service.ZhimiOrderExtendService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import javax.validation.Valid;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * @author sunlife
 * @date:2020/4/27 3:54 下午
 * description: 智米dubbo接口
 */
@Slf4j
@Api(value = "智米H5接口", tags = {"智米H5接口"})
@Service(loadbalance = "roundrobin", timeout = 5000, version = DubboConsts.INTERFACE_VERSION)
public class ZhimiRemoteServiceImpl implements ZhimiRemoteService {

    @Autowired
    private ZhimiOrderExtendService zhimiOrderExtendService;

    /**
     * 根据SN码获取相关信息
     */
    @Override
    @ApiOperation(value = "查询SN码相关信息")
    public ResponseDTO<CheckResultDRO> checkSNCode(Long workId, String snCode, String thirdModelCode) {
        log.info("查询SN码相关信息 workId=[{}], snCode=[{}],  thirdModelCode=[{}]", workId, snCode, thirdModelCode);
        if (ZhimiConsts.SN_GLOBAL.equals(snCode)) {
            if (StringUtil.isBlank(thirdModelCode)) {
                return ResponseDTO.fail("指定三级机型不能为空");
            }
        }

        CheckResultDRO dro = null;
        try {
            CheckResultDTO dto = zhimiOrderExtendService.checkSNCode(workId, snCode, thirdModelCode);
            dro = BeanMapper.map(dto, CheckResultDRO.class);
        } catch (Exception e) {
            log.error(String.valueOf(e.getMessage()), e);
            throw e;
        }
        return ResponseDTO.success(dro);
    }


    /**
     * 根据新SN码获取相关信息
     */
    @Override
    @ApiOperation(value = "查询新SN码相关信息")
    public ResponseDTO<CheckResultDRO> checkNewSNCode(Long workId, String newSnCode) {
        log.info("查询新-SN码相关信息 workId=[{}], newSnCode=[{}]", workId, newSnCode);

        CheckResultDRO dro = null;
        try {
            CheckResultDTO dto = zhimiOrderExtendService.checkNewSNCode(workId, newSnCode);
            dro = BeanMapper.map(dto, CheckResultDRO.class);
        } catch (Exception e) {
            log.error(String.valueOf(e.getMessage()), e);
            throw e;
        }
        return ResponseDTO.success(dro);
    }

    /**
     * 保存购机日期
     */
    @Override
    @ApiOperation(value = "保存购机日期")
    public ResponseDTO<SaveBuyDateResulstDRO> saveBuyDate(ZhimiPartReturnFactoryDIO dio) throws OmsBaseException {
        log.info("保存购机日期入参 ZhimiPartReturnFactoryDIO=[{}]", JSON.toJSONString(dio));

        ResultDTO<SaveBuyDateResulstDTO> resultDTO;
        try {
            ZhimiOrderExtend zhimiOrderExtend = new ZhimiOrderExtend();
            zhimiOrderExtend.setOrderId(dio.getWorkId());
            zhimiOrderExtend.setBuyDate(dio.getBuyDate());

            resultDTO = zhimiOrderExtendService.saveBuyDate(zhimiOrderExtend);
        } catch (Exception e) {
            log.error(String.valueOf(e.getMessage()), e);
            throw e;
        }

        if (resultDTO.isStatusBool()) {
            SaveBuyDateResulstDTO dto = resultDTO.getData();
            SaveBuyDateResulstDRO dro = BeanMapper.map(dto, SaveBuyDateResulstDRO.class);
            return ResponseDTO.success(dro);
        } else {
            return ResponseDTO.fail(resultDTO.getMessage());
        }
    }


    /**
     * 保存返厂物流信息
     *
     * @return
     */
    @Override
    @ApiOperation(value = "保存返厂物流信息")
    public ResponseDTO saveReturnFactoryExpress(ZhimiPartReturnFactoryDIO dio) throws OmsBaseException {
        log.info("保存返厂物流信息入参 ZhimiPartReturnFactoryDIO=[{}]", JSON.toJSONString(dio));

        if (NumberUtil.isNullOrZero(dio.getWorkId())) {
            return ResponseDTO.fail("订单ID不能为空");
        }

        if (StringUtils.isBlank(dio.getExpressCode())) {
            return ResponseDTO.fail("快递单号不能为空");
        }

        if (StringUtils.isBlank(dio.getExpressCompanyCode())) {
            return ResponseDTO.fail("快递公司编号不能为空");
        }

        ResultDTO resultDTO;
        try {
            ZhimiOrderExtend zhimiOrderExtend = new ZhimiOrderExtend();
            zhimiOrderExtend.setOrderId(dio.getWorkId());
            ZhimiOrderExtend.ReturnFactoryExpress returnFactoryExpress = new ZhimiOrderExtend.ReturnFactoryExpress();
            returnFactoryExpress.setExpressCode(dio.getExpressCode());
            returnFactoryExpress.setExpressCompanyCode(dio.getExpressCompanyCode());
            returnFactoryExpress.setExpressCompany(dio.getExpressCompany());
            returnFactoryExpress.setExpressTime(dio.getExpressTime());
            zhimiOrderExtend.setReturnFactoryExpress(returnFactoryExpress);

            resultDTO = zhimiOrderExtendService.saveReturnFactoryExpress(zhimiOrderExtend);
        } catch (Exception e) {
            log.error(String.valueOf(e.getMessage()), e);
            throw e;
        }

        if (resultDTO.isStatusBool()) {
            return ResponseDTO.success();
        } else {
            return ResponseDTO.fail(resultDTO.getMessage());
        }
    }

    /**
     * 查询故障列表
     */
    @Override
    public ResponseDTO<List<KVDict<String>>> getFaultList(Long workId) {
        log.info("查询故障列表 请求：{}", workId);
        List<KVDict<String>> faultList = null;
        try {
            faultList = zhimiOrderExtendService.getFaultList(workId);
        } catch (Exception e) {
            log.error(String.valueOf(e.getMessage()), e);
            throw e;
        }
        return ResponseDTO.success(faultList);
    }

    /**
     * 保存故障列表
     */
    @Override
    public ResponseDTO saveFault(ZhimiDIO dio) {
        log.info("保存故障列表 请求：{}", JSON.toJSONString(dio));
        if (Objects.isNull(dio.getWorkId())) {
            ResponseDTO.fail("订单ID不能为空");
        }
        if (CollectionUtil.isNullOrEmpty(dio.getFaults())) {
            ResponseDTO.fail("故障列表不能为空");
        }

        ResultDTO resultDTO = null;

        try {
            // 组装数据
            ZhimiOrderExtend zhimiOrderExtend = new ZhimiOrderExtend();
            zhimiOrderExtend.setOrderId(dio.getWorkId());
            List<ZhimiOrderExtend.Fault> faults = Lists.newArrayList();
            dio.getFaults().forEach(fault -> {
                ZhimiOrderExtend.Fault zhimiFault = new ZhimiOrderExtend.Fault();
                zhimiFault.setCode(fault.getCode());
                zhimiFault.setName(fault.getName());
                faults.add(zhimiFault);
            });
            zhimiOrderExtend.setFaults(faults);

            resultDTO = zhimiOrderExtendService.saveOrderFaults(zhimiOrderExtend);
        } catch (Exception e) {
            log.error(String.valueOf(e.getMessage()), e);
            throw e;
        }

        if (resultDTO.isStatusBool()) {
            return ResponseDTO.success();
        } else {
            return ResponseDTO.fail(resultDTO.getMessage());
        }
    }

    /**
     * 查询配件
     */
    @Override
    public ResponseDTO<ZhimiPartInfoVO> getPartList(Long workId) {
        log.info("查询配件 请求参数：{}", JSON.toJSONString(workId));

        ZhimiPartInfoVO zhimiPartInfoVO = null;

        try {
            ZhimiOrderExtend partExtend = zhimiOrderExtendService.getPartList(workId);

            zhimiPartInfoVO = new ZhimiPartInfoVO();
            zhimiPartInfoVO.setWorkId(partExtend.getOrderId());
            if (partExtend.getPostAddress() != null) {
                zhimiPartInfoVO.setAddress(BeanMapper.map(partExtend.getPostAddress(), ZhimiAddressVO.class));
            }
            List<KVDict<String>> parts = partExtend.getParts().stream().map(part -> KVDict.<String>builder().value(part.getName()).text(part.getCode()).build()).collect(Collectors.toList());
            zhimiPartInfoVO.setParts(parts);
        } catch (Exception e) {
            log.error(String.valueOf(e.getMessage()), e);
            throw e;
        }

        //TODO
        return ResponseDTO.success(zhimiPartInfoVO);
    }

    /**
     * 申请配件
     */
    @Override
    public ResponseDTO applyPart(ZhimiDIO applyDIO) {
        log.info("申请配件 请求参数：{}", JSON.toJSONString(applyDIO));

        ResultDTO resultDTO = null;
        try {
            if (Objects.isNull(applyDIO.getWorkId())
                    || Objects.isNull(applyDIO.getReceiver())
                    || Objects.isNull(applyDIO.getAddress())
                    || Objects.isNull(applyDIO.getTelephone())
                    || CollectionUtil.isNullOrEmpty(applyDIO.getParts())) {
                return ResponseDTO.fail("信息不全，请补全：订单ID、收货人信息、配件信息");
            }

            // 组装数据
            ZhimiOrderExtend zhimiOrderExtend = new ZhimiOrderExtend();
            zhimiOrderExtend.setOrderId(applyDIO.getWorkId());

            // 地址信息
            ZhimiOrderExtend.PostAddress address = new ZhimiOrderExtend.PostAddress();
            address.setName(applyDIO.getReceiver());
            address.setPhone(applyDIO.getTelephone());
            address.setAddress(applyDIO.getAddress());
            zhimiOrderExtend.setPostAddress(address);

            // 配件信息
            List<ZhimiOrderExtend.Part> parts = Lists.newArrayList();
            applyDIO.getParts().forEach(part -> {
                ZhimiOrderExtend.Part zhimiPart = new ZhimiOrderExtend.Part();
                zhimiPart.setCode(part.getCode());
                zhimiPart.setName(part.getName());
                zhimiPart.setNumber(part.getNumber());
                parts.add(zhimiPart);
            });

            zhimiOrderExtend.setParts(parts);
            resultDTO = zhimiOrderExtendService.saveOrderParts(zhimiOrderExtend);
        } catch (Exception e) {
            log.error(String.valueOf(e.getMessage()), e);
            throw e;
        }

        if (resultDTO.isStatusBool()) {
            return ResponseDTO.success();
        } else {
            return ResponseDTO.fail(resultDTO.getMessage());
        }
    }

    /**
     * 查询工单配件信息
     */
    @Override
    public ResponseDTO<List<ZhimiPartVO>> getWorkPartList(ZhimiBaseDIO dio) {
        log.info("查询工单配件信息 请求参数：{}", JSON.toJSONString(dio));
        if (Objects.isNull(dio.getWorkId())) {
            return ResponseDTO.fail("订单ID不能为空");
        }

        List<ZhimiPartVO> partVO = null;
        try {
            List<ZhimiOrderExtend.Part> orderParts = zhimiOrderExtendService.getAppliedPartList(dio.getWorkId());
            partVO = this.getPartVO(orderParts);
        } catch (Exception e) {
            log.error(String.valueOf(e.getMessage()), e);
            throw e;
        }

        return ResponseDTO.success(partVO);
    }

    /**
     * 保存检测结果
     */
    @Override
    public ResponseDTO checkResult(@Valid ZhimiResultDIO resultDIO) throws OmsBaseException {
        log.info("保存检测结果 请求参数：{}", JSON.toJSONString(resultDIO));

        Integer type = resultDIO.getResult();
        if (!Objects.equals(ZhimiConsts.NO, type) && !Objects.equals(ZhimiConsts.DETECTION_DAP, type)
                && !Objects.equals(ZhimiConsts.DETECTION_DOA, type)) {
            return ResponseDTO.fail("请选择正确的检测结果");
        }

        try {
            ZhimiOrderExtend zhimiOrderExtend = new ZhimiOrderExtend();
            zhimiOrderExtend.setOrderId(resultDIO.getWorkId());
            ZhimiOrderExtend.Detection detection = new ZhimiOrderExtend.Detection();
            detection.setType(type);
            detection.setRemark(resultDIO.getReason());
            zhimiOrderExtend.setDetection(detection);
            zhimiOrderExtendService.saveZhimiOrderExtendLocalInfo(zhimiOrderExtend);
        } catch (Exception e) {
            log.error(String.valueOf(e.getMessage()), e);
            throw e;
        }
        return ResponseDTO.success();
    }

    /**
     * 保存勘测结果
     */
    @Override
    public ResponseDTO surveyResult(@Valid ZhimiResultDIO resultDIO) throws OmsBaseException {
        log.info("保存勘测结果 请求参数：{}", JSON.toJSONString(resultDIO));

        Integer type = resultDIO.getResult();
        if (!Objects.equals(ZhimiConsts.NO, type) && !Objects.equals(ZhimiConsts.YES, type)) {
            return ResponseDTO.fail("请选择正确的勘测结果");
        }
        ZhimiConsts.SurveyReason surveyReason = ZhimiConsts.getSurveyReason(resultDIO.getReason());
        if (surveyReason == null) {
            return ResponseDTO.fail("请选择正确的原因");
        }

        try {
            ZhimiOrderExtend zhimiOrderExtend = new ZhimiOrderExtend();
            zhimiOrderExtend.setOrderId(resultDIO.getWorkId());
            ZhimiOrderExtend.Survey survey = new ZhimiOrderExtend.Survey();
            survey.setState(type);
            survey.setRemark(surveyReason.getCode());
            zhimiOrderExtend.setSurvey(survey);
            zhimiOrderExtendService.saveZhimiOrderExtendLocalInfo(zhimiOrderExtend);
        } catch (Exception e) {
            log.error(String.valueOf(e.getMessage()), e);
            throw e;
        }
        return ResponseDTO.success();
    }

    /**
     * 保存退货类型
     */
    @Override
    public ResponseDTO retundResult(@Valid ZhimiResultDIO resultDIO) throws OmsBaseException {
        log.info("保存退货类型 请求参数：{}", JSON.toJSONString(resultDIO));

        Integer type = resultDIO.getResult();
        if (!Objects.equals(ZhimiConsts.NO, type) && !Objects.equals(ZhimiConsts.RETURN_FORCE, type)
                && !Objects.equals(ZhimiConsts.RETURN_BROKEN, type)
                && !Objects.equals(ZhimiConsts.RETURN_POST_WRONG, type)) {
            return ResponseDTO.fail("请选择正确的退货类型");
        }

        try {
            ZhimiOrderExtend zhimiOrderExtend = new ZhimiOrderExtend();
            zhimiOrderExtend.setOrderId(resultDIO.getWorkId());
            ZhimiOrderExtend.Retund retund = new ZhimiOrderExtend.Retund();
            retund.setType(type);
            zhimiOrderExtend.setRetund(retund);
            zhimiOrderExtendService.saveZhimiOrderExtendLocalInfo(zhimiOrderExtend);
        } catch (Exception e) {
            log.error(String.valueOf(e.getMessage()), e);
            throw e;
        }
        return ResponseDTO.success();
    }

    /**
     * 保存换机类型
     */
    @Override
    public ResponseDTO exchangeResult(@Valid ZhimiResultDIO resultDIO) throws OmsBaseException {
        log.info("保存换机类型 请求参数：{}", JSON.toJSONString(resultDIO));

        Integer type = resultDIO.getResult();
        if (!Objects.equals(ZhimiConsts.NO, type) && !Objects.equals(ZhimiConsts.EXCHANGE_DAP, type)
                && !Objects.equals(ZhimiConsts.EXCHANGE_DOA, type)
                && !Objects.equals(ZhimiConsts.EXCHANGE_OTHER, type)) {
            return ResponseDTO.fail("请选择正确的换机类型");
        }

        try {
            ZhimiOrderExtend zhimiOrderExtend = new ZhimiOrderExtend();
            zhimiOrderExtend.setOrderId(resultDIO.getWorkId());
            ZhimiOrderExtend.Exchange exchange = new ZhimiOrderExtend.Exchange();
            exchange.setType(type);
            zhimiOrderExtend.setExchange(exchange);
            zhimiOrderExtendService.saveZhimiOrderExtendLocalInfo(zhimiOrderExtend);
        } catch (Exception e) {
            log.error(String.valueOf(e.getMessage()), e);
            throw e;
        }
        return ResponseDTO.success();
    }

    @Override
    public ResponseDTO<ZhimiVO> getOrderInfo(Long workId) {
        ZhimiVO zhimiVO = null;
        try {
            ZhimiOrderExtend orderinfo = zhimiOrderExtendService.findZhimiOrderExtendByOrderId(workId);
            zhimiVO = BeanMapper.map(orderinfo, ZhimiVO.class);
            zhimiVO.setWorkId(orderinfo.getOrderId());

            List<ZhimiOrderExtend.Part> orderParts = zhimiOrderExtendService.getAppliedPartList(workId);
            List<ZhimiPartVO> parts = this.getPartVO(orderParts);
            zhimiVO.setParts(parts);

            // 是否需要重新下换机单
            Integer reOrderExchange = GlobalConsts.NO;
            if (Objects.equals(ZhimiConsts.SERVICE_TYPE_REPAIR, orderinfo.getServiceType())
                    && Objects.equals(GlobalConsts.YES, orderinfo.getReplaceOnly())) {
                reOrderExchange = GlobalConsts.YES;
            }
            zhimiVO.setReOrderExchange(reOrderExchange);
        } catch (Exception e) {
            log.error(String.valueOf(e.getMessage()), e);
            throw e;
        }

        return ResponseDTO.success(zhimiVO);
    }

    public List<ZhimiPartVO> getPartVO(List<ZhimiOrderExtend.Part> orderParts) {
        List<ZhimiPartVO> zhimiPartVOS = Lists.newArrayList();

        List<ZhimiOrderExtend.Part> noExpressCodeParts = orderParts.stream().filter(item -> item.getExpressCode() == null).collect(Collectors.toList());

        Map<String, List<ZhimiOrderExtend.Part>> partMap = orderParts.stream().filter(item -> item.getExpressCode() != null).collect(Collectors.groupingBy(ZhimiOrderExtend.Part::getExpressCode));

        partMap.put("", noExpressCodeParts);

        partMap.forEach((expressCode, parts) -> {
            if (CollectionUtil.isNullOrEmpty(parts)) {
                return;
            }

            ZhimiPartVO zhimipartVO = new ZhimiPartVO();
            zhimipartVO.setExpressCode(expressCode);
            zhimipartVO.setExpressCompany(parts.get(0).getExpressCompany());
            zhimipartVO.setExpressTime(parts.get(0).getExpressTime());
            zhimipartVO.setApplyTime(parts.get(0).getApplyTime());
            List<PartVO> partVOS = Lists.newArrayListWithCapacity(parts.size());
            parts.forEach(part -> {
                PartVO partVO = new PartVO();
                partVO.setCode(part.getCode());
                partVO.setName(part.getName());
                partVO.setNumber(part.getNumber());
                partVOS.add(partVO);
            });
            zhimipartVO.setParts(partVOS);
            zhimiPartVOS.add(zhimipartVO);
        });
        return zhimiPartVOS;
    }

}
